﻿using jiuyuan.数据.基础数据类;
using jiuyuan.数据.怪物类;
using jiuyuan.数据.玩家类;
using jiuyuan.管理器;
using jiuyuan.服务;
using Microsoft.Extensions.Logging;
using jiuyuan.数据.共享类; // 添加这个using语句

namespace jiuyuan.服务;

// 操作结果类
public class 操作结果
{
    public bool 是否成功 { get; set; }
    public string 消息 { get; set; } = string.Empty;

    public static 操作结果 成功(string 消息 = "")
    {
        return new 操作结果 { 是否成功 = true, 消息 = 消息 };
    }

    public static 操作结果 失败(string 消息)
    {
        return new 操作结果 { 是否成功 = false, 消息 = 消息 };
    }
}

// 技能执行结果类
public class 技能执行结果
{
    public bool 是否成功 { get; set; }
    public string 消息 { get; set; } = string.Empty;
    public int 消耗魔法值 { get; set; }

    public static 技能执行结果 成功(string 消息 = "")
    {
        return new 技能执行结果 { 是否成功 = true, 消息 = 消息 };
    }

    public static 技能执行结果 失败(string 消息)
    {
        return new 技能执行结果 { 是否成功 = false, 消息 = 消息 };
    }
}

// 游戏主服务
public class 游戏主服务(
    事件总线 事件总线,
    技能管理器 技能管理器,
    装备管理器 装备管理器,
    副本管理器 副本管理器,
    怪物AI管理器 怪物AI管理器,
    战斗管理器 战斗管理器,
    玩家决策服务 玩家决策服务,
    配置加载器 配置加载器,
    ILogger<游戏主服务> 日志器)
{
    private readonly 事件总线 _事件总线 = 事件总线;
    private readonly 技能管理器 _技能管理器 = 技能管理器;
    private readonly 装备管理器 _装备管理器 = 装备管理器;
    private readonly 副本管理器 _副本管理器 = 副本管理器;
    private readonly 怪物AI管理器 _怪物AI管理器 = 怪物AI管理器;
    private readonly 战斗管理器 _战斗管理器 = 战斗管理器;
    private readonly 玩家决策服务 _玩家决策服务 = 玩家决策服务;
    private readonly 配置加载器 _配置加载器 = 配置加载器;
    private readonly ILogger<游戏主服务> _日志器 = 日志器;

    /// <summary>
    /// 初始化游戏系统
    /// </summary>
    public async Task 初始化()
    {
        _日志器.LogInformation("初始化游戏系统");

        // 注册全局事件处理
        注册事件处理();

        await Task.CompletedTask;
    }

    /// <summary>
    /// 玩家进入游戏
    /// </summary>
    public async Task 玩家进入游戏(玩家 玩家)
    {
        _日志器.LogInformation("玩家 {玩家名称} 进入游戏", 玩家.名称);

        // 发布玩家进入游戏事件
        await _事件总线.发布事件(new 玩家进入游戏事件 { 玩家 = 玩家 });

        // 初始化玩家属性
        玩家.重新计算属性();
    }

    /// <summary>
    /// 玩家离开游戏
    /// </summary>
    public async Task 玩家离开游戏(玩家 玩家)
    {
        _日志器.LogInformation("玩家 {玩家名称} 离开游戏", 玩家.名称);

        // 如果玩家在副本中，自动放弃副本
        // if (_副本管理器.获取玩家当前副本(玩家) != null)
        // {
        //     await _副本管理器.放弃副本(玩家);
        // }

        // 发布玩家离开游戏事件
        await _事件总线.发布事件(new 玩家离开游戏事件 { 玩家 = 玩家 });
    }

    /// <summary>
    /// 创建队伍并进入副本
    /// </summary>
    public async Task<副本实例?> 创建队伍进入副本(List<玩家> 玩家队伍, 副本配置 副本配置)
    {
        _日志器.LogInformation("创建队伍进入副本 {副本名称}", 副本配置.名称);

        // 检查玩家等级是否满足副本要求
        foreach (var 玩家 in 玩家队伍)
        {
            if (玩家.等级 < 副本配置.等级要求)
            {
                _日志器.LogWarning("玩家 {玩家名称} 等级不足，无法进入副本 {副本名称}", 玩家.名称, 副本配置.名称);
                return null;
            }
        }

        // 创建游戏副本实例
        // var 副本实例 = await _副本管理器.创建游戏副本(副本配置, 玩家队伍);
        var 副本实例 = new 副本实例
        {
            Id = Guid.NewGuid(),
            副本配置 = 副本配置,
            玩家队伍 = 玩家队伍,
            怪物队伍 = 副本配置.怪物生成配置列表.SelectMany(m => 
                Enumerable.Repeat(m.怪物详情!, m.数量)).ToList(),
            当前进度 = 0,
            是否完成 = false
        };

        if (副本实例 != null)
        {
            // 发布进入副本事件
            await _事件总线.发布事件(new 进入副本事件 { 副本实例 = 副本实例 });

            _日志器.LogInformation("队伍成功进入副本 {副本名称}", 副本配置.名称);
        }
        else
        {
            _日志器.LogError("创建游戏副本失败: {副本名称}", 副本配置.名称);
        }

        return 副本实例;
    }

    /// <summary>
    /// 玩家使用技能
    /// </summary>
    public async Task<技能执行结果> 玩家使用技能(玩家 玩家, 游戏元素 技能, List<战斗单位> 目标列表)
    {
        _日志器.LogInformation("玩家 {玩家名称} 使用技能 {技能名称}", 玩家.名称, 技能.名称);

        // 检查玩家是否拥有该技能
        var 拥有技能 = 玩家.技能仓库.Any(s => s.Id == 技能.Id && s.类型 == 物品类型.技能);
        if (!拥有技能)
        {
            return 技能执行结果.失败($"玩家未学习技能: {技能.名称}");
        }

        // 执行技能
        var 结果 = await _技能管理器.执行技能(玩家, 技能, 目标列表, _战斗管理器);

        // 注意：这里需要修复类型转换问题
        return new 技能执行结果 { 是否成功 = 结果.是否成功, 消息 = 结果.消息 };
    }

    /// <summary>
    /// 玩家使用技能（通过名称，保持向后兼容）
    /// </summary>
    public async Task<技能执行结果> 玩家使用技能(玩家 玩家, string 技能名称, List<战斗单位> 目标列表)
    {
        _日志器.LogInformation("玩家 {玩家名称} 使用技能 {技能名称}", 玩家.名称, 技能名称);

        // 检查玩家是否拥有该技能
        var 拥有技能 = 玩家.技能仓库.Any(s => s.名称 == 技能名称 && s.类型 == 物品类型.技能);
        if (!拥有技能)
        {
            return 技能执行结果.失败($"玩家未学习技能: {技能名称}");
        }

        // 执行技能
        var 结果 = await _技能管理器.执行技能(玩家, 技能名称, 目标列表, _战斗管理器);

        // 注意：这里需要修复类型转换问题
        return new 技能执行结果 { 是否成功 = 结果.是否成功, 消息 = 结果.消息 };
    }

    /// <summary>
    /// 设置玩家技能槽
    /// </summary>
    public async Task<bool> 设置玩家技能槽(玩家 玩家, List<游戏元素> 技能列表)
    {
        // 检查技能数量是否超过限制
        if (技能列表.Count > 5)
        {
            _日志器.LogWarning("玩家 {玩家名称} 尝试设置超过5个技能", 玩家.名称);
            return false;
        }

        // 检查玩家是否拥有这些技能
        foreach (var 技能 in 技能列表)
        {
            if (!玩家.拥有技能(技能.Id))
            {
                _日志器.LogWarning("玩家 {玩家名称} 尝试设置未拥有的技能 {技能名称}", 玩家.名称, 技能.名称);
                return false;
            }
        }

        // 更新玩家技能槽
        玩家.当前技能槽.Clear();
        foreach (var 技能 in 技能列表)
        {
            玩家.当前技能槽.Add(技能);
        }

        _日志器.LogInformation("玩家 {玩家名称} 更新了技能槽", 玩家.名称);

        // 发布技能槽更新事件
        await _事件总线.发布事件(new 技能槽更新事件 { 玩家 = 玩家, 技能列表 = 技能列表 });

        return true;
    }

    /// <summary>
    /// 玩家学习技能
    /// </summary>
    public async Task<bool> 玩家学习技能(玩家 玩家, 游戏元素 技能)
    {
        // 检查玩家等级是否满足技能要求
        if (玩家.等级 < 技能.等级要求)
        {
            _日志器.LogWarning("玩家 {玩家名称} 等级不足，无法学习技能 {技能名称}", 玩家.名称, 技能.名称);
            return false;
        }

        // 检查是否已经学会该技能
        if (玩家.拥有技能(技能.Id))
        {
            _日志器.LogWarning("玩家 {玩家名称} 已经学会技能 {技能名称}", 玩家.名称, 技能.名称);
            return false;
        }

        // 添加技能到玩家技能仓库
        玩家.技能仓库.Add(技能);

        _日志器.LogInformation("玩家 {玩家名称} 学会了技能 {技能名称}", 玩家.名称, 技能.名称);

        // 发布学习技能事件
        await _事件总线.发布事件(new 学习技能事件 { 玩家 = 玩家, 技能 = 技能 });

        return true;
    }

    /// <summary>
    /// 玩家获得经验
    /// </summary>
    public async Task<bool> 玩家获得经验(玩家 玩家, int 经验值)
    {
        玩家.经验值 += 经验值;

        _日志器.LogInformation("玩家 {玩家名称} 获得 {经验值} 点经验", 玩家.名称, 经验值);

        // 检查是否升级
        var 升级所需经验 = 计算升级所需经验(玩家.等级);
        if (玩家.经验值 >= 升级所需经验)
        {
            玩家.等级++;
            玩家.经验值 -= 升级所需经验;

            _日志器.LogInformation("玩家 {玩家名称} 升级到 {等级} 级", 玩家.名称, 玩家.等级);

            // 发布升级事件
            await _事件总线.发布事件(new 玩家升级事件 { 玩家 = 玩家, 新等级 = 玩家.等级 });

            // 重新计算属性
            玩家.重新计算属性();
        }

        return true;
    }

    /// <summary>
    /// 计算升级所需经验
    /// </summary>
    private int 计算升级所需经验(int 当前等级)
    {
        // 简单的升级公式：等级 * 100
        return 当前等级 * 100;
    }

    /// <summary>
    /// 注册事件处理
    /// </summary>
    private void 注册事件处理()
    {
        // 处理玩家进入游戏副本事件
        _事件总线.订阅事件<进入副本事件>(async 事件 =>
        {
            _日志器.LogInformation("游戏副本 {副本名称} 已创建", 事件.副本实例.副本配置.名称);

            // 启动游戏副本
            // await _副本管理器.启动本(事件.副本实例);
        });

        // 处理游戏副本完成事件
        _事件总线.订阅事件<游戏副本完成事件>(async 事件 =>
        {
            _日志器.LogInformation("游戏副本 {副本名称} 已完成", 事件.副本实例.副本配置.名称);

            // 给予奖励
            foreach (var 玩家 in 事件.副本实例.玩家队伍)
            {
                // 给予经验奖励
                // 注意：这里需要修复经验奖励属性引用问题
                // await 玩家获得经验(玩家, 事件.副本实例.副本配置.经验奖励);

                // 给予物品奖励
                foreach (var 奖励 in 事件.副本实例.副本配置.通关奖励)
                {
                    // 这里应该调用物品管理器来给予奖励
                    _日志器.LogInformation("玩家 {玩家名称} 获得奖励物品 {物品名称}", 玩家.名称, 奖励.物品详情.名称);
                }
            }
        });
    }
}

// 游戏事件类
public class 玩家进入游戏事件 : 游戏事件
{
    public 玩家 玩家 { get; set; } = null!;
}

public class 玩家离开游戏事件 : 游戏事件
{
    public 玩家 玩家 { get; set; } = null!;
}

public class 进入副本事件 : 游戏事件
{
    public 副本实例 副本实例 { get; set; } = null!;
}

public class 游戏副本完成事件 : 游戏事件
{
    public 副本实例 副本实例 { get; set; } = null!;
}

public class 技能槽更新事件 : 游戏事件
{
    public 玩家 玩家 { get; set; } = null!;
    public List<游戏元素> 技能列表 { get; set; } = [];
}

public class 学习技能事件 : 游戏事件
{
    public 玩家 玩家 { get; set; } = null!;
    public 游戏元素 技能 { get; set; } = null!;
}

public class 玩家升级事件 : 游戏事件
{
    public 玩家 玩家 { get; set; } = null!;
    public int 新等级 { get; set; }
}

// 副本实例类
public class 副本实例
{
    public Guid Id { get; set; }
    public 副本配置 副本配置 { get; set; } = null!;
    public List<玩家> 玩家队伍 { get; set; } = [];
    public List<怪物> 怪物队伍 { get; set; } = [];
    public int 当前进度 { get; set; }
    public bool 是否完成 { get; set; }
}